package cn.sdormitory.wx.service.impl;

import cn.sdormitory.basedata.dao.BStudentDao;
import cn.sdormitory.basedata.entity.BStudent;
import cn.sdormitory.common.exception.ApiException;
import cn.sdormitory.common.sms.TxSmsTemplate;
import cn.sdormitory.common.utils.RedisUtils;
import cn.sdormitory.sys.dao.SysUserDao;
import cn.sdormitory.sys.entity.SysUser;
import cn.sdormitory.wx.service.WechatOpenIdService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Optional;

/**
 * @author : yy
 * @date: 2024/12/13 14:44
 * @description:
 */
@Service
public class WechatOpenIdServiceImpl implements WechatOpenIdService {
    @Autowired
    private TxSmsTemplate txSmsTemplate;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private BStudentDao bStudentDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void sendValidCode(String phone) throws ApiException{
        if(StringUtils.isEmpty(phone)){
            throw new ApiException("请输入手机号码");
        }

        String bindFlag = redisUtils.get("bind:validCode:" + phone);
        if(!StringUtils.isEmpty(bindFlag)){
            throw new ApiException("请勿重复发送");
        }

        //生成随机4位数的验证码
        String code = String.valueOf(Math.round((Math.random()+1) * 1000));
        String[] params = {code};

        String resultStr = txSmsTemplate.sendMesModel(phone,params,0);
        if("OK".equals(resultStr)){
            //发送成功，将验证码保存到缓存中，设置3分钟过期，验证成功后删除
            redisUtils.set("bind:validCode:" + phone,code,180L);
        }else {
            throw new ApiException(resultStr);
        }
    }

    @Override
    public void updateStuWxOpenId(String name, String phone, String code, String openId) {
        String cacheCode = redisUtils.get("bind:validCode:" + phone);
        if(!code.equals(cacheCode)){
            throw new ApiException("验证码不正确");
        }
        redisUtils.delete("bind:validCode:" + phone);

        LambdaQueryWrapper<BStudent> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(BStudent::getPhone, phone);
        studentWrapper.eq(BStudent::getStudentName,name);
        BStudent student = bStudentDao.selectOne(studentWrapper);
        if(!Optional.ofNullable(student).isPresent()) {
            throw new ApiException("与系统录入信息不匹配,请联系班主任处理!");
        }

        student.setWxOpenId(openId);
        bStudentDao.updateById(student);
    }

    @Override
    public void updateParentWxOpenId(String studentName, String studentPhone, String phone, String code, String openId) {
        String cacheCode = redisUtils.get("bind:validCode:" + phone);
        if(!code.equals(cacheCode)){
            throw new ApiException("验证码不正确");
        }
        redisUtils.delete("bind:validCode:" + phone);

        LambdaQueryWrapper<BStudent> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(BStudent::getPhone, studentPhone);
        studentWrapper.eq(BStudent::getStudentName,studentName);
        studentWrapper.eq(BStudent::getParentPhone,phone);
        BStudent student = bStudentDao.selectOne(studentWrapper);
        if(!Optional.ofNullable(student).isPresent()) {
            throw new ApiException("与系统录入信息不匹配,请联系班主任处理!");
        }
        student.setParentWxOpenId(openId);
        bStudentDao.updateById(student);
    }

    @Override
    public void updateTeacherWxOpenId(String accessNo, String password, String openId) {
        SysUser sysUser = sysUserDao.doLogin(accessNo);
        if(!passwordEncoder.matches(password,sysUser.getPassword())){
            throw new ApiException("账号密码不正确!");
        }

        LambdaUpdateWrapper<SysUser> userWrapper = new LambdaUpdateWrapper<>();
        userWrapper.set(SysUser::getWxOpenId,openId);
        userWrapper.eq(SysUser::getPhone,accessNo);
        sysUserDao.update(null,userWrapper);
    }
}
